package com.hrg.rds.infra.connect.protocol.modbus;

import cn.hutool.core.util.HexUtil;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.plc4x.java.api.PlcConnection;
import org.apache.plc4x.java.api.messages.PlcReadRequest;
import org.apache.plc4x.java.api.messages.PlcReadResponse;
import org.apache.plc4x.java.api.messages.PlcWriteRequest;
import org.apache.plc4x.java.api.messages.PlcWriteResponse;
import org.apache.plc4x.java.api.types.PlcResponseCode;
import org.apache.plc4x.java.api.value.PlcValue;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

// 返回16进制小写字符串
@Slf4j
public class ModbusUtil {
	private final static String TagPrefix = "value-";
	private final static int Timeout = 2;

	public static List<String> readBatch(PlcConnection connection, List<ModbusSingleReq> queryList) throws Exception {
		List<String> result = new ArrayList<>();
		// holding-register:5678
		PlcReadRequest.Builder builder = connection.readRequestBuilder();
		for (int i = 0; i < queryList.size(); i++) {
			ModbusSingleReq modbusSingleReq = queryList.get(i);
			String tagAddress = String.format("%s%d", modbusSingleReq.getModbusMemoryArea().getPrefixEn(), modbusSingleReq.getStartAddress());
			String tagName = TagPrefix+i;
			builder.addTagAddress(tagName, tagAddress);
		}
		PlcReadRequest readRequest = builder.build();
		//同步
		PlcReadResponse response = readRequest.execute().get(Timeout, TimeUnit.SECONDS);
		for (int i = 0; i < queryList.size(); i++) {
			String tagName = TagPrefix+i;
			if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
				PlcValue plcValue = response.getPlcValue(tagName);
				if (plcValue.isNull()) {
					result.add(null);
				} else {
					result.add(HexUtil.encodeHexStr(plcValue.getRaw()));
				}
			}
		}
		return result;
	}

	public static String readSingle(PlcConnection connection, ModbusSingleReq modbusSingleReq) throws Exception {
		String result = null;
		// holding-register:5678
		String tagAddress = String.format("%s%d", modbusSingleReq.getModbusMemoryArea().getPrefixEn(), modbusSingleReq.getStartAddress());
		PlcReadRequest.Builder builder = connection.readRequestBuilder();
		String tagName = TagPrefix+0;
		builder.addTagAddress(tagName, tagAddress);
		PlcReadRequest readRequest = builder.build();
		//同步
		PlcReadResponse response = readRequest.execute().get(Timeout, TimeUnit.SECONDS);
		if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
			PlcValue plcValue = response.getPlcValue(tagName);
			if (!plcValue.isNull()) {
				result = HexUtil.encodeHexStr(plcValue.getRaw());
			}
		}
		return result;
	}

	public static boolean writeSingle(PlcConnection connection, ModbusSingleReq modbusSingleReq) throws Exception {
		boolean result = false;
		// holding-register:5678
		String tagAddress = String.format("%s%d", modbusSingleReq.getModbusMemoryArea().getPrefixEn(), modbusSingleReq.getStartAddress());
		PlcWriteRequest.Builder builder = connection.writeRequestBuilder();
		String tagName = TagPrefix+0;
		builder.addTagAddress(tagName, tagAddress, modbusSingleReq.getValue());
		PlcWriteRequest writeRequest = builder.build();
		//同步
		PlcWriteResponse response = writeRequest.execute().get(Timeout, TimeUnit.SECONDS);
		if (response.getResponseCode(tagName) == PlcResponseCode.OK) {
			result = true;
		}
		return result;
	}
}

